/**
 * 优化的亮度调整函数，专为调色盘设计
 * 基于主体色生成 0-140 范围内的相关颜色
 * @param color RGB 或十六进制颜色值
 * @param level 亮度等级 (0-140)，70为原色，0-70变暗，70-140变亮
 * @returns 调整后的十六进制颜色值
 */
export function adjustBrightness(color: string, level: number = 70): string {
  // 标准化输入范围
  level = Math.max(0, Math.min(140, level));

  // 转换输入颜色为 RGB
  let b: number, g: number, r: number;

  if (color.startsWith('#')) {
    // 处理十六进制颜色
    const rgb = hexToRgb(color);
    const match = rgb.match(/rgb\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*\)/);
    if (!match) throw new Error('Invalid color format');
    r = Number.parseInt(match[1] ?? '0', 10);
    g = Number.parseInt(match[2] ?? '0', 10);
    b = Number.parseInt(match[3] ?? '0', 10);
  } else {
    // 处理 RGB 颜色
    const match = color.match(/rgb\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*\)/);
    if (!match) throw new Error('Invalid RGB color format');
    r = Number.parseInt(match[1] ?? '0', 10);
    g = Number.parseInt(match[2] ?? '0', 10);
    b = Number.parseInt(match[3] ?? '0', 10);
  }

  // 将 RGB 转换为 HSL 以便更好地控制亮度
  const { h, s, l } = rgbToHsl(r, g, b);

  // 计算新的亮度值，以 level = 70 作为原色基准
  let targetLightness: number;
  let targetSaturation = s;

  if (level === 70) {
    // level = 70 返回原颜色
    targetLightness = l;
  } else if (level < 70) {
    // level 0-70: 变暗处理
    // 将 0-70 映射到 0.05-l（原亮度）
    const darkenFactor = level / 70;
    targetLightness = 0.05 + (l - 0.05) * darkenFactor;

    // 暗色时适当降低饱和度，避免过于鲜艳
    if (level < 20) {
      targetSaturation = s * (0.4 + (level / 20) * 0.6);
    }
  } else {
    // level 70-140: 变亮处理
    // 将 70-140 映射到 l（原亮度）-0.95
    const brightenFactor = (level - 70) / 70;
    targetLightness = l + (0.95 - l) * brightenFactor;

    // 亮色时适当降低饱和度，避免过于刺眼
    if (level > 120) {
      targetSaturation = s * (1 - ((level - 120) / 20) * 0.3);
    }
  }

  // 将 HSL 转回 RGB
  const {
    b: newB,
    g: newG,
    r: newR,
  } = hslToRgb(h, targetSaturation, targetLightness);

  // 返回十六进制格式
  const toHex = (n: number) => Math.round(n).toString(16).padStart(2, '0');
  return `#${toHex(newR)}${toHex(newG)}${toHex(newB)}`;
}

/**
 * 将 RGB 转换为 HSL
 */
function rgbToHsl(
  r: number,
  g: number,
  b: number,
): { h: number; l: number; s: number } {
  r /= 255;
  g /= 255;
  b /= 255;

  const max = Math.max(r, g, b);
  const min = Math.min(r, g, b);
  const diff = max - min;

  // 计算亮度
  const l = (max + min) / 2;

  // 计算饱和度
  let s = 0;
  if (diff !== 0) {
    s = l > 0.5 ? diff / (2 - max - min) : diff / (max + min);
  }

  // 计算色相
  let h = 0;
  if (diff !== 0) {
    switch (max) {
      case b: {
        h = ((r - g) / diff + 4) / 6;
        break;
      }
      case g: {
        h = ((b - r) / diff + 2) / 6;
        break;
      }
      case r: {
        h = ((g - b) / diff + (g < b ? 6 : 0)) / 6;
        break;
      }
    }
  }

  return { h, s, l };
}

/**
 * 将 HSL 转换为 RGB
 */
function hslToRgb(
  h: number,
  s: number,
  l: number,
): { b: number; g: number; r: number } {
  let b: number, g: number, r: number;

  if (s === 0) {
    r = g = b = l; // 灰色
  } else {
    const q = l < 0.5 ? l * (1 + s) : l + s - l * s;
    const p = 2 * l - q;
    r = hueToRgb(p, q, h + 1 / 3);
    g = hueToRgb(p, q, h);
    b = hueToRgb(p, q, h - 1 / 3);
  }

  return { r: r * 255, g: g * 255, b: b * 255 };
}

/**
 * 生成基于主体色的调色盘
 * @param baseColor 主体色（RGB 或十六进制）
 * @param steps 生成的颜色数量，默认10个
 * @returns 包含不同亮度等级的颜色数组
 */
export function generateColorPalette(
  baseColor: string,
  steps: number = 10,
): string[] {
  const palette: string[] = [];
  const stepSize = 140 / (steps - 1);

  for (let i = 0; i < steps; i++) {
    const level = Math.round(i * stepSize);
    palette.push(adjustBrightness(baseColor, level));
  }

  return palette;
}

function hueToRgb(p: number, q: number, t: number) {
  if (t < 0) t += 1;
  if (t > 1) t -= 1;
  if (t < 1 / 6) return p + (q - p) * 6 * t;
  if (t < 1 / 2) return q;
  if (t < 2 / 3) return p + (q - p) * (2 / 3 - t) * 6;
  return p;
}

export function hslToColor(color: string) {
  // 提取 HSL 值
  const match = color.match(/hsl\(\s*(\d+)\s+(\d+)%\s+(\d+)%\s*\)/);
  if (!match) return color; // 如果不是有效的 HSL 格式，返回原始颜色

  const h = Number.parseInt(match[1] ?? '0', 10) / 360; // 色相
  const s = Number.parseInt(match[2] ?? '0', 10) / 100; // 饱和度
  const l = Number.parseInt(match[3] ?? '0', 10) / 100; // 明度

  // 转换 HSL 到 RGB
  let b, g, r;
  if (s === 0) {
    r = g = b = l * 255; // 灰色
  } else {
    const q = l < 0.5 ? l * (1 + s) : l + s - l * s;
    const p = 2 * l - q;
    r = hueToRgb(p, q, h + 1 / 3) * 255;
    g = hueToRgb(p, q, h) * 255;
    b = hueToRgb(p, q, h - 1 / 3) * 255;
  }

  // 返回十六进制颜色值
  return `#${((1 << 24) + (Math.round(r) << 16) + (Math.round(g) << 8) + Math.round(b)).toString(16).slice(1)}`;
}

/**
 * 将十六进制颜色值转换为 RGB 格式
 * @param hex 十六进制颜色值，如 #3aa0f3 或 3aa0f3
 * @returns RGB 格式字符串，如 rgb(58, 160, 243)
 */
export function hexToRgb(hex: string): string {
  // 移除 # 符号
  hex = hex.replace('#', '');

  // 如果是 3 位十六进制，转换为 6 位
  if (hex.length === 3) {
    hex = [...hex].map((char) => char + char).join('');
  }

  if (hex.length !== 6) {
    throw new Error('Invalid hex color format');
  }

  const r = Number.parseInt(hex.slice(0, 2), 16);
  const g = Number.parseInt(hex.slice(2, 4), 16);
  const b = Number.parseInt(hex.slice(4, 6), 16);

  return `rgb(${r}, ${g}, ${b})`;
}

/**
 * 将 RGB 格式转换为十六进制颜色值
 * @param rgb RGB 格式字符串，如 rgb(58, 160, 243)
 * @returns 十六进制颜色值，如 #3aa0f3
 */
export function rgbToHex(rgb: string): string {
  const match = rgb.match(/rgb\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*\)/);
  if (!match) {
    throw new Error('Invalid RGB color format');
  }

  const r = Number.parseInt(match[1] ?? '0', 10);
  const g = Number.parseInt(match[2] ?? '0', 10);
  const b = Number.parseInt(match[3] ?? '0', 10);

  const toHex = (n: number) => n.toString(16).padStart(2, '0');

  return `#${toHex(r)}${toHex(g)}${toHex(b)}`;
}

/**
 * 验证十六进制颜色值格式是否有效
 * @param hex 十六进制颜色值
 * @returns 是否为有效格式
 */
export function isValidHex(hex: string): boolean {
  const hexPattern = /^#?(?:[a-f0-9]{6}|[a-f0-9]{3})$/i;
  return hexPattern.test(hex);
}

/**
 * 调整十六进制颜色的亮度
 * @param hex 十六进制颜色值，如 #3aa0f3
 * @param brightness 亮度调整值（-255 到 255）
 * @returns 调整后的十六进制颜色值
 */
export function adjustHexBrightness(hex: string, brightness: number): string {
  const rgb = hexToRgb(hex);
  const adjustedRgb = adjustBrightness(rgb, brightness);
  return rgbToHex(adjustedRgb);
}
